package java8.optional.demo02;

import java8.optional.Insurance;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.Objects;
import java.util.Optional;

/**
 * @author ChangLiang
 * @date 2020/4/21
 */
public class OptionalApiUsage {

    @Test
    @DisplayName("test Optional API")
    public void test() {

        // 构造方式1
        Optional<Insurance> insuranceOptional = Optional.empty();
//        insuranceOptional.get();

        // 构造方式2
        Optional<Insurance> insuranceOptional1 = Optional.of(new Insurance());
        insuranceOptional1.get();

        // 构造方式3
        // 综合了前面的两种方式
        Optional<Object> objectOptional = Optional.ofNullable(null);
        objectOptional.orElseGet(Insurance::new);

        //
        objectOptional.orElse(new Insurance());

//        objectOptional.orElseThrow(RuntimeException::new);

//        objectOptional.orElseThrow(() -> new RuntimeException("not have reference"));

        // 如果对象不符合条件，将会返回一个空的Optional
        Insurance insurance = insuranceOptional1.filter(i -> i.getName() == null).get();
        System.out.println(insurance);

        Optional<String> nameOptional = insuranceOptional1.map(i -> i.getName());
        System.out.println(nameOptional.isPresent());
        System.out.println(nameOptional.orElse("empty String"));

    }

    @Test
    @DisplayName("test has name")
    public void test2(){
        Insurance insurance = new Insurance();
//        insurance.setName("aaa");
        Optional<Insurance> insuranceOptional = Optional.of(insurance);
        Optional<String> nameOptional = insuranceOptional.map(i -> i.getName());
        System.out.println(nameOptional.isPresent());
        // 当Optional为空 不输出
        nameOptional.ifPresent(System.out::println);
    }

    @Test
    @DisplayName("test optional")
    public void test4(){
        // output unknown
        System.out.println(getInsuranceName(null));
        // output unknown
        System.out.println(getInsuranceName(new Insurance()));

        System.out.println(getInsuranceNameWithOptional(null));
        System.out.println(getInsuranceNameWithOptional(new Insurance()));

    }

    private String getInsuranceName(Insurance insurance) {
        final String UNKNOWN = "unknown";
        if (Objects.isNull(insurance)) {
            return UNKNOWN;
        }
        if (Objects.isNull(insurance.getName())) {
            return UNKNOWN;
        }
        return insurance.getName();
    }

    /**
     * 比如这个insurance是外部接口调用返回的
     * @param insurance
     * @return
     */
    private String getInsuranceNameWithOptional(Insurance insurance) {
        return Optional.ofNullable(insurance).map(Insurance::getName).orElse("unknown");
    }
}
